﻿using System;
using System.Collections;
using System.Drawing;

namespace CSharp进阶_容器
{
	class Test { }
	class Program
	{
		#region ArrayList使用
		//static void Main(string[] args)
		//{
		//	ArrayList arr = new ArrayList();
		//	#region 增
		//	arr.Add(1);
		//	arr.Add(3.14);
		//	arr.Add("hello");
		//	arr.Add(new Test());
		//	arr.AddRange(new int[] { 5, 6, 6, 7 });
		//	arr.Insert(1, "world");
		//	arr.InsertRange(2, new string[] { "java", "c++" });
		//	Show(arr);
		//	#endregion
		//	#region 删
		//	arr.Remove(1);
		//	Show(arr);
		//	arr.RemoveAt(0);
		//	Show(arr);
		//	arr.RemoveRange(1, 3);
		//	Show(arr);
		//	#endregion
		//	#region 查
		//	{
		//		if (arr.Contains(6))
		//		{
		//			Console.WriteLine("存在 6");
		//		}
		//		else
		//		{
		//			Console.WriteLine("不存在 6");
		//		}
		//		int idx = arr.IndexOf(6, 0, arr.Count);
		//		if (idx != -1)
		//		{
		//			Console.WriteLine("找到了 6，下标为{0}", idx);
		//		}
		//		else
		//		{
		//			Console.WriteLine("没有找到 6");
		//		}
		//		idx = arr.LastIndexOf(6, arr.Count - 1, arr.Count);
		//		if (idx != -1)
		//		{
		//			Console.WriteLine("找到了 6，下标为{0}", idx);
		//		}
		//		else
		//		{
		//			Console.WriteLine("没有找到 6");
		//		}
		//	}
		//	#endregion
		//	#region 改
		//	arr[0] = new string("未来");
		//	Show(arr);
		//	#endregion

		//	#region 装箱 拆箱
		//	// 装箱：值类型存入引用类型中，值类型从栈复制到堆
		//	// 拆箱：引用类型取出值类型转换使用，从堆复制到栈
		//	#endregion
		//}
		//static void Show(ArrayList arr)
		//{
		//	#region 遍历
		//	//Console.WriteLine("==========================");
		//	//Console.WriteLine("arr.Count: " + arr.Count);
		//	//Console.WriteLine("arr.Capacity: " + arr.Capacity);
		//	//Console.Write("value: ");
		//	//for (int i = 0; i < arr.Count; i++)
		//	//{
		//	//	Console.Write(" " + arr[i]);
		//	//}
		//	//Console.WriteLine();
		//	//Console.WriteLine("==========================");

		//	Console.WriteLine("==========================");
		//	Console.WriteLine("arr.Count: " + arr.Count);
		//	Console.WriteLine("arr.Capacity: " + arr.Capacity);
		//	Console.Write("value: ");
		//	foreach (var item in arr)
		//	{
		//		Console.Write(" " + item);
		//	}
		//	Console.WriteLine();
		//	Console.WriteLine("==========================");
		//	#endregion
		//}
		#endregion
		static void Main(string[] args)
		{
			BackpackManager bpm = new BackpackManager(1000);
			bpm.Buy(new Item(1, 10));
			bpm.Buy(new Item(1, 10));
			bpm.Buy(new Item(2, 10));
			bpm.Buy(new Item(2, 10));
			bpm.Show();
			bpm.sell(new Item(1, 5));
			bpm.sell(new Item(2, 10));
			bpm.Show();
		}
	}
	enum E_ItemType
	{
		None,
		Apple,
		Banana
	}
	static class Util
	{
		public static float GetItemPrice(E_ItemType type)
		{
			switch (type)
			{
				case E_ItemType.Apple:
					return 10f;
				case E_ItemType.Banana:
					return 20f;
			}
			return 0;
		}
		public static string GetItemName(E_ItemType type)
		{
			switch (type)
			{
				case E_ItemType.Apple:
					return "apple";
				case E_ItemType.Banana:
					return "banana";
			}
			return "";
		}
		public static int GetItemId(E_ItemType type)
		{
			switch (type)
			{
				case E_ItemType.Apple:
					return 1;
				case E_ItemType.Banana:
					return 2;
			}
			return -1;
		}
		public static E_ItemType GetItemType(int id)
		{
			switch (id)
			{
				case 1:
					return E_ItemType.Apple;
				case 2:
					return E_ItemType.Banana;
			}
			return E_ItemType.None;
		}
	}
	class Item
	{
		public int Id { get; set; }
		public string Name { get; set; }
		public float Price { get; set; }
		public int Count { get; set; }
		public E_ItemType Type { get; set; }
		public Item(int id, int count = 1) : this(Util.GetItemType(id), count)
		{
			//Id = id;
			//Count = count;
			//Type = Util.GetItemType(id);
			//Name = Util.GetItemName(Type);
			//Price = Util.GetItemPrice(Type);
		}
		public Item(E_ItemType type, int count = 1)
		{
			Type = type;
			Count = count;
			Id = Util.GetItemId(Type);
			Name = Util.GetItemName(Type);
			Price = Util.GetItemPrice(Type);
		}
		public override string ToString()
		{
			return "\t" + Id + "\t" + Name + "\t" + Count + "\t" + Price + "\t" + Type;
		}
	}
	class BackpackManager
	{
		private ArrayList backpack_;
		private float balance_;
		public BackpackManager(float balance = 100f, int capacity = 50)
		{
			backpack_ = new ArrayList(capacity);
			balance_ = balance;
		}
		public float Balance
		{
			get
			{
				return balance_;
			}
			set
			{
				balance_ = value;
			}
		}
		public void Buy(Item item)
		{
			float cost = item.Price * item.Count;
			if (balance_ < cost)
			{
				Console.WriteLine("Not enough money");
				return;
			}
			int idx = Find(item.Id);
			if (idx != -1)
			{
				(backpack_[idx] as Item).Count += item.Count;
			}
			else
			{
				backpack_.Add(item);
			}
			balance_ -= cost;
			Console.WriteLine("成功买了 {0} 个 {1} 花费了 {2} 钱，余额 {3} 钱", 
				item.Count, item.Name, cost, balance_);
		}
		private int Find(int id)
		{
			for (int i = 0; i < backpack_.Count; i++)
			{
				if ((backpack_[i] as Item).Id == id)
					return i;
			}
			return -1;
		}
		public void sell(Item item)
		{
			int idx = Find(item.Id);
			if (idx == -1)
			{
				Console.WriteLine("Sell " + item.Name + " faild!  no exist!");
				return;
			}
			int count;
			float price = item.Price;
			if (item.Count < (backpack_[idx] as Item).Count)
			{
				count = item.Count;
				(backpack_[idx] as Item).Count -= count;
			}
			else
			{
				count = (backpack_[idx] as Item).Count;
				backpack_.RemoveAt(idx);

			}

			float profit = item.Price * count * 0.7f;
			balance_ += profit;
			Console.WriteLine("成功卖出 {0} 个 {1}，卖了 {2} 钱，余额 {3} 钱", 
				count, item.Name, profit, balance_);
		}
		public void sell(int id, int count = 1)
		{
			Item item = new Item(id, count);
			sell(item);
		}
		public void Show(string name)
		{
			Console.WriteLine("------------------------------------------");
			Console.WriteLine("Backpack:");
			Console.WriteLine("Balance: " + balance_);
			
			(int left, int top) = Console.GetCursorPosition();
			Console.SetCursorPosition(0, top);
			Console.Write("\tid");
			Console.Write("\tname");
			Console.Write("\tcount");
			Console.Write("\tprice");
			Console.WriteLine("\ttype");
			foreach (var item_ in backpack_)
			{
				if (name == (item_ as Item).Name)
					Console.WriteLine(item_);
			}
			Console.WriteLine("------------------------------------------");
		}
		public void Show()
		{
			Console.WriteLine("------------------------------------------");
			Console.WriteLine("Backpack:");
			Console.WriteLine("Balance: " + balance_);

			(int left, int top) = Console.GetCursorPosition();
			Console.SetCursorPosition(0, top);
			Console.Write("\tid");
			Console.Write("\tname");
			Console.Write("\tcount");
			Console.Write("\tprice");
			Console.WriteLine("\ttype");
			foreach (var item_ in backpack_)
			{
				Console.WriteLine(item_);
			}
			Console.WriteLine("------------------------------------------");
		}
	}
}
